'''
    除法的算式由被除数、除数，中间加一个除号组成
    被除数代表总共有多少个正方形
    除数代表每组中要分配的正方形的个数
    除法运算的结果代表可以将所有的正方形分成多少组
    除法的计算过程，可以理解为先在x轴上画出第一组正方形
    然后在y轴方向上，重复画这组正方形，直到把所有的正方形都用完
    最后y轴上的长度，也就是除法计算的结果了
'''
from manim import *

class DivisionVisualization(Scene):
    def construct(self):
        # 设置被除数和除数
        dividend = 13
        divisor = 3
        
        # 创建自定义 LaTeX 模板
        tex_template = TexTemplate()
        tex_template.add_to_preamble(r"\usepackage{ctex}")

        # 设置坐标轴的长度，使得 x 和 y 的单位长度一致，并且增加一些额外的空间
        unit_length = 1
        rows = dividend // divisor
        cols = divisor
        
        # 动态调整单位长度，确保坐标轴在屏幕内
        max_dimension = max(rows, cols)
        unit_length = 3 / max_dimension  # 6 是一个经验值，可以根据需要调整
        
        axes = Axes(
            x_range=[0, cols + 2, 1],
            y_range=[0, rows + 2, 1],
            x_length=(cols + 2) * unit_length,
            y_length=(rows + 2) * unit_length,
            axis_config={"include_numbers": True},
        ).add_coordinates().shift(UP * 0.5)

        # 创建 x 轴上的线段（代表除数）
        x_line = Line(
            start=axes.c2p(0, 0),
            end=axes.c2p(cols, 0),
            color=BLUE
        )
        
        # 创建 y 轴上的线段（代表商）
        y_line = Line(
            start=axes.c2p(0, 0),
            end=axes.c2p(0, rows),
            color=RED
        )

        # 创建行和列的标签
        x_label = Tex(f"除数: {cols}", color=BLUE, tex_template=tex_template).next_to(axes, DOWN).scale(0.7)
        
        # 创建除法表达式（不显示结果）
        division_expression = Tex(f"${dividend} \\div {divisor}$", color=WHITE)
        division_expression.to_edge(UP)

        # 创建除法结果表达式
        result_expression = Tex(f"${dividend} \\div {divisor} = {rows} \\text{{ 余 }} {dividend % divisor}$", color=WHITE, tex_template=tex_template)
        result_expression.next_to(division_expression, DOWN)

        # 显示除法表达式（不显示结果）
        self.play(Write(division_expression))
        
        # 显示坐标轴
        self.play(Create(axes))
        

        
        # 创建被除数的正方形矩阵
        initial_squares = VGroup()
        for i in range(dividend):
            square = Square(side_length=unit_length)
            square.set_fill(YELLOW, opacity=0.5)
            square.set_stroke(GREEN_E, width=2)
            row_offset = (i // 10) * unit_length  # 每行 6 个正方形
            col_offset = (i % 10) * unit_length
            square.move_to(2 * UP - row_offset * DOWN + col_offset * RIGHT)
            initial_squares.add(square)
        initial_squares.next_to(division_expression, DOWN).align_to(division_expression, LEFT)
        # 显示所有正方形
        self.play(LaggedStart(*[Create(square) for square in initial_squares], lag_ratio=0.1))

        # 添加文字说明，强调被除数的意义
        dividend_explanation = Tex(f"被除数 {dividend} 代表正方形的总个数", color=WHITE, tex_template=tex_template).scale(0.7)
        dividend_explanation.next_to(initial_squares, DOWN, buff=0.5)
        self.play(Write(dividend_explanation))
        self.wait(2)
        self.play(FadeOut(dividend_explanation))
        
        # 添加文字说明，强调除数的意义
        divisor_explanation = Tex(f"除数 {divisor} 表示每组包含的正方形个数", color=WHITE, tex_template=tex_template).scale(0.7)
        divisor_explanation.next_to(initial_squares, DOWN, buff=0.5)
        self.play(Write(divisor_explanation))
        self.wait(2)
        self.play(FadeOut(divisor_explanation))
        
        # 显示 x 轴上的线段（除数）
        self.play(Create(x_line))
        self.play(Write(x_label))
        


        # 创建最终的正方形矩阵
        matrix_squares = VGroup()
        for i in range(rows):
            for j in range(cols):
                square = Square(side_length=unit_length)
                square.set_fill(GREEN if i > 0 else YELLOW, opacity=0.5)  # 第一行用黄色，其它行用绿色
                square.set_stroke(GREEN_E, width=2)
                square.move_to(axes.c2p(j + 0.5, i + 0.5))
                matrix_squares.add(square)



        # 移动正方形到最终位置
        self.play(LaggedStart(*[Transform(initial_squares[i], matrix_squares[i]) for i in range(min(len(initial_squares), len(matrix_squares)))], lag_ratio=0.1))       
        # 添加文字说明，强调商的意义
        quotient_explanation = Tex(f"商表示可以分成的组数", color=WHITE, tex_template=tex_template).scale(0.7)
        quotient_explanation.next_to(result_expression, DOWN, buff=0.5)
        self.play(Write(quotient_explanation))
        self.play(FadeOut(quotient_explanation))
        # 显示 y 轴上的线段（商）
        self.play(Create(y_line))
        y_label = Tex(f"商: {rows}", color=RED, tex_template=tex_template).next_to(axes, LEFT).scale(0.7)
        self.play(Write(y_label))        
        # 添加关于余数的说明
        remainder = dividend % divisor

            
           

        if remainder > 0:
            remainder_explanation = Tex(f"余数 {remainder} 表示剩余的正方形", color=WHITE, tex_template=tex_template).scale(0.7)
            remainder_explanation.next_to(initial_squares, RIGHT)
            self.play(Write(remainder_explanation))
            self.play(FadeOut(remainder_explanation))   
            # 显示余数部分
            remainder_squares = VGroup()
            for i in range(remainder):
                square = Square(side_length=unit_length)
                square.set_fill(RED, opacity=0.5)  # 用红色表示余数部分
                square.set_stroke(GREEN_E, width=2)
                square.move_to(axes.c2p(i + 0.5, rows + 0.5))  # 放在最后一行的后面
                remainder_squares.add(square)
            # 如何让initial_squares剩余的正方形fade out？？？
            # 让 initial_squares 中剩余的正方形淡出
            remaining_squares = initial_squares[len(matrix_squares):]
            self.play(FadeOut(remaining_squares))
            self.play(LaggedStart(*[Create(square) for square in remainder_squares], lag_ratio=0.1))                     
        

        
        # 显示除法结果表达式
        self.play(Transform(division_expression, result_expression))
              
        # 保持动画一段时间
        self.wait(2)

# 运行代码
# 保存修改后的 Python 文件（例如 DivisionVisualization.py），然后在命令行中运行以下命令：
# manim -pql .\DivisionVisualization.py DivisionVisualization